package com.suray.wcs.service.pojo;

import com.suray.basic.wcs.path.core.Node;
import com.suray.basic.wcs.path.enums.NodeType;
import com.suray.basic.wcs.plc.utils.PlcUnit;
import com.suray.basic.wcs.utils.LoggerUtil;
import com.suray.basic.wcs.utils.ModuleType;
import com.suray.basic.wcs.utils.WcsFuncUtil;
import com.suray.commin.core.utils.SpringContextHolder;
import com.suray.commin.core.utils.StringUtils;
import com.suray.rgv.Rgv60Interface;
import com.suray.rgv.util.ErrorInfo;
import com.suray.wcs.res.enums.PalletStatus;
import com.suray.wcs.res.enums.RgvStatus;
import com.suray.wcs.service.enums.ElectricStatus;
import com.suray.wcs.service.enums.NotificationTypeEnum;
import com.suray.wcs.service.pojo.rgv.rgv.protocol.util.RgvCargoStatus;
import com.suray.wcs.service.system.entity.RgvDB;
import com.suray.wcs.service.system.service.impl.NodeDBServiceImpl;
import com.suray.wcs.service.system.service.impl.RgvDBServiceImpl;
import com.suray.wcs.service.util.WcsUtil;

import java.io.IOException;

public class Rgv60 extends Rgv {

    private NodeDBServiceImpl nodeDBService = SpringContextHolder.getBean(NodeDBServiceImpl.class);


    protected static final RgvDBServiceImpl rgvDBService = SpringContextHolder.getBean(RgvDBServiceImpl.class);

    //校验标记
    private boolean checkFlag = true;

    /**
     * 6代车核心
     */
    protected Rgv60Interface rgvCore;

    protected ModuleType moduleType;

    /**
     * 每一个DB对象对应一个业务对象
     *
     * @param rgvDB
     * @param moduleType
     */
    public Rgv60(RgvDB rgvDB, Rgv60Interface rgvCore, ModuleType moduleType) {
        super(rgvDB);
        this.rgvCore = rgvCore;
        this.moduleType = moduleType;
        try {
            rgvCore.init();
        } catch (Exception e) {
            WcsFuncUtil.exceptionLog(e, this.getClass());
            WcsUtil.notification(getRgvName() + "初始化失败", NotificationTypeEnum.ERROR);
        }
    }

    public Rgv60Interface getRgvCore() {
        return rgvCore;
    }

    public void analyzeData() {
        Node tempNode = rgvCore.getLocation();
        Node node = nodeDBService.getNodeByRgvPoint(tempNode.getRgv60Point());
        Integer floor = rgvCore.getCurrentFloor();
        if (StringUtils.isNotEmpty(tempNode.getRgv60Point())) {
            groundCode = tempNode.getRgv60Point();
            if (node != null && floor != null) {
                if (node.getNodeType().equals(NodeType.L)) {
                    node.setZ(floor);
                    resetLocation(node);
                } else if (floor.equals(node.getZ())) {
                    resetLocation(node);
                } else {
                    LoggerUtil.warn("小车当前载入地图错误，请确认小车地图加载是否正确", this.getClass());
                }
            } else {
                resetLocation(null);
            }
        }
        palletStatus = rgvCore.getRgvPalletStatus();
        battery = rgvCore.getBatSoc().intValue();
        // 默认未开启
        hasPallet = RgvCargoStatus.INVALID;
        setElectricStatus(ElectricStatus.parseStatus(battery, this));
        if (rgvCore.isOnline()) {
            if (rgvStatus != RgvStatus.ERROR) {
                rgvStatus = analyzeRgvStatus();
                rgvResStatus = RgvStatus.READY;
            }
        } else {
            rgvStatus = RgvStatus.OFF_LINE;
            rgvResStatus = RgvStatus.OFF_LINE;
        }
        checkLifterLayer(node,floor);
        if (rgvStatus == RgvStatus.ERROR) {
            if (StringUtils.isEmpty(errorMessage)) {
                ErrorInfo errorInfo = rgvCore.getErrorInfo();
                if (errorInfo != null) {
                    errorMessage = rgvCore.getErrorInfo().getErrorMessage();
                }
            }
        }
    }

    @Override
    public PalletStatus getPalletStatus() {
        return rgvCore.getRgvPalletStatus();
    }

    /**
     * 不能把子车状态一起处理，子车的信息不是实时刷新的
     * @return
     */
    private RgvStatus analyzeRgvStatus() {
        return rgvCore.getRgvStatus();
    }

    /**
     * 检测
     * @param node
     * @param seerMapLayer
     */
    private void checkLifterLayer(Node node, Integer seerMapLayer){
        if(node == null || seerMapLayer == null){
            return;
        }
        if(checkFlag){
            if(node.getNodeType() == NodeType.L){
                if(seerMapLayer.equals(node.getZ()) ||
                        seerMapLayer != PlcUnit.getLifterOper(node).getHoistCurrentLayer()){
                    setRgvStatus(RgvStatus.ERROR);
                    setErrorMessage("位置异常,请手动切换小车层信息");
                }
            }
            checkFlag = false;
        }
    }

    /**
     * 更新小车位置
     * @param node
     */
    protected void resetLocation(Node node) {
        try {
            if (node != null) {
                if (!node.equals(getRgvDB().getLocationNode())) {
                    getRgvDB().setLocation(node.toString());
                    rgvDBService.updateRgvLocation(getRgvDB());
                }
                this.setCurLocation(node);
            }
        } catch (Exception e) {
            WcsFuncUtil.exceptionLog(e, this.getClass());
        }
    }

    @Override
    public void setInterrupt(boolean interrupt) {
        super.setInterrupt(interrupt);

        if (interrupt) {
            try {
                rgvCore.setInterrupt();
            } catch (IOException e) {
                throw new RuntimeException("写入小车中断时，通讯失败");
            }
        }
    }

    @Override
    public void checkInterrupt(String msg, long checkTime) {
        super.checkInterrupt(msg, checkTime);
        if (!rgvCore.hasAuthor()) {
            LoggerUtil.error("小车没有控制权", this.getClass());
            throw new RuntimeException("小车没有控制权, 小车可能被重启或则控制权被其它服务抢占, 请重新抢占控制权后恢复任务");
        }
    }

    /**
     * 小车变为故障状态
     */
    public void rgvError(ErrorInfo errorInfo) {
        rgvStatus = RgvStatus.ERROR;
        rgvCore.rgvError(errorInfo);
    }

    public void resetRgv() throws IOException {
        rgvCore.recovery();
    }
}
